
# ifndef __DFX_VECTOR4_H__
# define __DFX_VECTOR4_H__

# include "dfxCore.h"

namespace DFX
{
    class DFX_EXPORT Vector4
    {
    public:

        Float32     X;
        Float32     Y;
        Float32     Z;
        Float32     W;

    public:

        Vector4(Float32 f = 0.0f)
            : X(0.0f), Y(0.0f), Z(0.0f), W(0.0f)
        {
        }

        Vector4(Float32 x, Float32 y, Float32 z, Float32 w)
            : X(x), Y(y), Z(z), W(w)
        {
        }

        Vector4(const Vector4 &v)
            : X(v.X), Y(v.Y), Z(v.Z), W(v.W)
        {
        }

        inline Float32 GetLengthSqr() const
        {
            return X * X + Y * Y + Z * Z + W * W;
        }

        inline Float32 GetLength() const
        {
            return sqrtf(X * X + Y * Y + Z * Z + W * W);
        }

        inline Float32 Dot(const Vector4 &v) const
        {
            return X * v.X + Y * v.Y + Z * v.Z + W * v.W;
        }        

        inline void Normalize()
        {
            Float32 length = sqrtf(X * X + Y * Y + Z * Z + W * W);

            if (length != 0.0f)
            {
                Float32 invLen = 1.0f / length;

                X *= invLen;
                Y *= invLen;
                Z *= invLen;
                W *= invLen;
            }
        }

        inline Vector4 operator + (const Vector4 &v) const
        {
            return Vector4(X + v.X, Y + v.Y, Z + v.Z, W + v.W);
        }

        inline Vector4 operator - (const Vector4 &v) const
        {
            return Vector4(X - v.X, Y - v.Y, Z - v.Z, W - v.W);
        }

        inline Vector4 operator * (float f) const
        {
            return Vector4(X * f, Y * f, Z * f, W * f);
        }

        inline Vector4 operator / (float f) const
        {
            return Vector4(X / f, Y / f, Z / f, W / f);
        }

        inline Vector4& operator += (const Vector4 &v)
        {
            X += v.X;
            Y += v.Y;
            Z += v.Z;
            W += v.W;

            return *this;
        }

        inline Vector4& operator -= (const Vector4 &v)
        {
            X -= v.X;
            Y -= v.Y;
            Z -= v.Z;
            W -= v.W;

            return *this;
        }

        inline Vector4& operator *= (float f)
        {
            X *= f;
            Y *= f;
            Z *= f;
            W *= f;

            return *this;
        }

        inline bool operator == (const Vector4 &v) const
        {
            return X == v.X && Y == v.Y && Z == v.Z && W == v.W;
        }

        inline bool operator != (const Vector4 &v) const
        {
            return X != v.X || Y != v.Y || Z != v.Z || W != v.W;
        }
    };
}

# endif